#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_system.h>
#include <esp_log.h>
#include <string.h>
#include "driver/gpio.h"
#include "rc523.h"
#include "iic.h"

#include "../../main/main.h"

static i2c_master_dev_handle_t nfc_dev;

static const char *TAG = "rc523";

card_info_t card_info;

#define RC523_ADDR 0x01
#define I2C_SPEED 100000

#define RST_PIN_NUM 1

#define MAXRLEN 64

// 循环获取任务
TaskHandle_t xGET_rfid_TaskHandle = NULL;
// 获取任务
TaskHandle_t xSET_rfid_TaskHandle = NULL;

// #define BIT0 0x01
// #define BIT1 0x02
// #define BIT2 0x04
// #define BIT3 0x08
// #define BIT4 0x10
// #define BIT5 0x20
// #define BIT6 0x40
// #define BIT7 0x80

/////////////////////////////////////////////////////////////////////
// �?    能：寻卡
// 参数说明: req_code[IN]:寻卡方式
//                 0x52 = 寻感应区内所有符�?14443A标准的卡
//                 0x26 = 寻未进入休眠状态的�?
//           pTagType[OUT]：卡片类型代�?
//                 0x4400 = Mifare_UltraLight
//                 0x0400 = Mifare_One(S50)
//                 0x0200 = Mifare_One(S70)
//                 0x0800 = Mifare_Pro(X)
//                 0x4403 = Mifare_DESFire
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRequest(unsigned char req_code, unsigned char *pTagType)
{
	char status;
	unsigned int unLen;
	unsigned char ucComMF522Buf[MAXRLEN];

	WriteRawRC(CommandReg, PCD_RESETPHASE);
	while (ReadRawRC(0x27) != 0x88)
		; // wait chip start ok

	ClearBitMask(Status2Reg, 0x08);
	WriteRawRC(BitFramingReg, 0x07);
	SetBitMask(TxControlReg, 0x03);

	ucComMF522Buf[0] = req_code;

	status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 1, ucComMF522Buf, &unLen);

	if ((status == MI_OK) && (unLen == 0x10))
	{
		*pTagType = ucComMF522Buf[0];
		*(pTagType + 1) = ucComMF522Buf[1];
	}
	else
	{
		status = MI_ERR;
	}

	return status;
}

/////////////////////////////////////////////////////////////////////
// �?    能：防冲�?
// 参数说明: pSnr[OUT]:卡片序列号，4字节
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdAnticoll(unsigned char *pSnr)
{
	char status;
	unsigned char i, snr_check = 0;
	unsigned int unLen;
	unsigned char ucComMF522Buf[MAXRLEN];

	ClearBitMask(Status2Reg, 0x08);
	WriteRawRC(BitFramingReg, 0x00);
	ClearBitMask(CollReg, 0x80);

	ucComMF522Buf[0] = PICC_ANTICOLL1;
	ucComMF522Buf[1] = 0x20;

	status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 2, ucComMF522Buf, &unLen);

	if (status == MI_OK)
	{
		for (i = 0; i < 4; i++)
		{
			*(pSnr + i) = ucComMF522Buf[i];
			snr_check ^= ucComMF522Buf[i];
		}
		if (snr_check != ucComMF522Buf[i])
		{
			status = MI_ERR;
		}
	}

	SetBitMask(CollReg, 0x80);
	return status;
}

/////////////////////////////////////////////////////////////////////
// �?    能：选定卡片
// 参数说明: pSnr[IN]:卡片序列号，4字节
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdSelect(unsigned char *pSnr)
{
	char status;
	unsigned char i;
	unsigned int unLen;
	unsigned char ucComMF522Buf[MAXRLEN];

	ucComMF522Buf[0] = PICC_ANTICOLL1;
	ucComMF522Buf[1] = 0x70;
	ucComMF522Buf[6] = 0;
	for (i = 0; i < 4; i++)
	{
		ucComMF522Buf[i + 2] = *(pSnr + i);
		ucComMF522Buf[6] ^= *(pSnr + i);
	}
	CalulateCRC(ucComMF522Buf, 7, &ucComMF522Buf[7]);

	ClearBitMask(Status2Reg, 0x08);

	status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 9, ucComMF522Buf, &unLen);

	if ((status == MI_OK) && (unLen == 0x18))
	{
		status = MI_OK;
	}
	else
	{
		status = MI_ERR;
	}

	return status;
}

/////////////////////////////////////////////////////////////////////
// �?    能：验证卡片密码
// 参数说明: auth_mode[IN]: 密码验证模式
//                  0x60 = 验证A密钥
//                  0x61 = 验证B密钥
//           addr[IN]：块地址
//           pKey[IN]：密�?
//           pSnr[IN]：卡片序列号�?4字节
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdAuthState(unsigned char auth_mode, unsigned char addr, unsigned char *pKey, unsigned char *pSnr)
{
	char status;
	unsigned int unLen;
	unsigned char i, ucComMF522Buf[MAXRLEN];

	ucComMF522Buf[0] = auth_mode;
	ucComMF522Buf[1] = addr;
	for (i = 0; i < 6; i++)
	{
		ucComMF522Buf[i + 2] = *(pKey + i);
	}
	for (i = 0; i < 6; i++)
	{
		ucComMF522Buf[i + 8] = *(pSnr + i);
	}

	status = PcdComMF522(PCD_AUTHENT, ucComMF522Buf, 12, ucComMF522Buf, &unLen);
	if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
	{
		status = MI_ERR;
	}

	return status;
}

/////////////////////////////////////////////////////////////////////
// �?    能：读取M1卡一块数�?
// 参数说明: addr[IN]：块地址
//           pData[OUT]：读出的数据�?16字节
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRead(unsigned char addr, unsigned char *pData)
{
	char status;
	unsigned int unLen;
	unsigned char i, ucComMF522Buf[MAXRLEN];

	ucComMF522Buf[0] = PICC_READ;
	ucComMF522Buf[1] = addr;
	CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

	status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
	if ((status == MI_OK) && (unLen == 0x90))
	{
		for (i = 0; i < 16; i++)
		{
			*(pData + i) = ucComMF522Buf[i];
		}
	}
	else
	{
		status = MI_ERR;
	}

	return status;
}

/////////////////////////////////////////////////////////////////////
// �?    能：写数据到M1卡一�?
// 参数说明: addr[IN]：块地址
//           pData[IN]：写入的数据�?16字节
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdWrite(unsigned char addr, unsigned char *pData)
{
	char status;
	unsigned int unLen;
	unsigned char i, ucComMF522Buf[MAXRLEN];

	ucComMF522Buf[0] = PICC_WRITE;
	ucComMF522Buf[1] = addr;
	CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

	status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

	if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
	{
		status = MI_ERR;
	}

	if (status == MI_OK)
	{
		for (i = 0; i < 16; i++)
		{
			ucComMF522Buf[i] = *(pData + i);
		}
		CalulateCRC(ucComMF522Buf, 16, &ucComMF522Buf[16]);

		status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 18, ucComMF522Buf, &unLen);
		if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
		{
			status = MI_ERR;
		}
	}

	return status;
}

/////////////////////////////////////////////////////////////////////
// �?    能：扣款和充�?
// 参数说明: dd_mode[IN]：命令字
//                0xC0 = 扣款
//                0xC1 = 充�?
//           addr[IN]：钱包地址
//           pValue[IN]�?4字节�?(�?)值，低位在前
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdValue(unsigned char dd_mode, unsigned char addr, unsigned char *pValue)
{
	char status;
	unsigned int unLen;
	unsigned char i, ucComMF522Buf[MAXRLEN];

	ucComMF522Buf[0] = dd_mode;
	ucComMF522Buf[1] = addr;
	CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

	status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

	if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
	{
		status = MI_ERR;
	}

	if (status == MI_OK)
	{
		for (i = 0; i < 16; i++)
		{
			ucComMF522Buf[i] = *(pValue + i);
		}
		CalulateCRC(ucComMF522Buf, 4, &ucComMF522Buf[4]);
		unLen = 0;
		status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 6, ucComMF522Buf, &unLen);
		if (status != MI_ERR)
		{
			status = MI_OK;
		}
	}

	if (status == MI_OK)
	{
		ucComMF522Buf[0] = PICC_TRANSFER;
		ucComMF522Buf[1] = addr;
		CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

		status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

		if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
		{
			status = MI_ERR;
		}
	}
	return status;
}

/////////////////////////////////////////////////////////////////////
// �?    能：备份钱包
// 参数说明: sourceaddr[IN]：源地址
//           goaladdr[IN]：目标地址
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr)
{
	char status;
	unsigned int unLen;
	unsigned char ucComMF522Buf[MAXRLEN];

	ucComMF522Buf[0] = PICC_RESTORE;
	ucComMF522Buf[1] = sourceaddr;
	CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

	status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

	if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
	{
		status = MI_ERR;
	}

	if (status == MI_OK)
	{
		ucComMF522Buf[0] = 0;
		ucComMF522Buf[1] = 0;
		ucComMF522Buf[2] = 0;
		ucComMF522Buf[3] = 0;
		CalulateCRC(ucComMF522Buf, 4, &ucComMF522Buf[4]);

		status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 6, ucComMF522Buf, &unLen);
		if (status != MI_ERR)
		{
			status = MI_OK;
		}
	}

	if (status != MI_OK)
	{
		return MI_ERR;
	}

	ucComMF522Buf[0] = PICC_TRANSFER;
	ucComMF522Buf[1] = goaladdr;

	CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

	status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

	if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
	{
		status = MI_ERR;
	}

	return status;
}

/////////////////////////////////////////////////////////////////////
// �?    能：命令卡片进入休眠状�?
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdHalt(void)
{
	unsigned int unLen;
	unsigned char ucComMF522Buf[MAXRLEN];

	ucComMF522Buf[0] = PICC_HALT;
	ucComMF522Buf[1] = 0;
	CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

	PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

	return MI_OK;
}

/////////////////////////////////////////////////////////////////////
// 用MF522计算CRC16函数
/////////////////////////////////////////////////////////////////////
void CalulateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData)
{
	unsigned char i, n;
	ClearBitMask(DivIrqReg, 0x04);
	WriteRawRC(CommandReg, PCD_IDLE);
	SetBitMask(FIFOLevelReg, 0x80);
	for (i = 0; i < len; i++)
	{
		WriteRawRC(FIFODataReg, *(pIndata + i));
	}
	WriteRawRC(CommandReg, PCD_CALCCRC);
	i = 0xFF;
	do
	{
		n = ReadRawRC(DivIrqReg);
		i--;
	} while ((i != 0) && !(n & 0x04));
	pOutData[0] = ReadRawRC(CRCResultRegL);
	pOutData[1] = ReadRawRC(CRCResultRegM);
}

void MFRC522_SleepUS(uint32_t us)
{
	uint32_t i;

	for (i = 0; i < 6 * us; i++)
		;
}

/////////////////////////////////////////////////////////////////////
// �?    能：复位RC522
// �?    �?: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdReset(void)
{
	gpio_set_level(RST_PIN_NUM, 1);
	vTaskDelay(pdMS_TO_TICKS(1));
	gpio_set_level(RST_PIN_NUM, 0);
	vTaskDelay(pdMS_TO_TICKS(1));
	gpio_set_level(RST_PIN_NUM, 1);
	vTaskDelay(pdMS_TO_TICKS(1));

	WriteRawRC(CommandReg, PCD_RESETPHASE);
	// MFRC522_SleepUS(200);

	while (ReadRawRC(0x27) != 0x88)
		; // wait chip start ok

	ClearBitMask(Status2Reg, BIT3);
	ClearBitMask(ComIEnReg, BIT7); // 高电平触发中�?

	WriteRawRC(ModeReg, 0x3D); // 和Mifare卡通讯，CRC初始�?0x6363
#if 0
	WriteRawRC(TReloadRegL,30);
	WriteRawRC(TReloadRegH,0);
	WriteRawRC(TModeReg,0x8D);
	WriteRawRC(TPrescalerReg,0x3E);
	WriteRawRC(TxAutoReg,0x40);
#endif

	WriteRawRC(RxSelReg, 0x88);	 // RxWait
	WriteRawRC(TxAutoReg, 0x40); // 15 //typeA
	WriteRawRC(TxModeReg, 0x00); // 12 //Tx Framing A
	WriteRawRC(RxModeReg, 0x00); // 13 //Rx framing A

	{
		u8 backup, adc;
		backup = ReadRawRC(0x37);
		WriteRawRC(0x37, 0x00);
		adc = ReadRawRC(0x37);
		if (adc == 0x11)
		{
			WriteRawRC(0x37, 0x5E);
			WriteRawRC(0x26, 0x48);
			WriteRawRC(0x17, 0x88);
			WriteRawRC(0x38, 0x6B);
			WriteRawRC(0x3A, 0x23);
			WriteRawRC(0x29, 0x12); // 0x0F); //调制指数
			WriteRawRC(0x3B, 0xA5);
		}
		else if (adc == 0x12)
		{
			WriteRawRC(0x37, 0x5E);
			WriteRawRC(0x17, 0x88);
			WriteRawRC(0x29, 0x12);
			WriteRawRC(0x35, 0xED);
			WriteRawRC(0x3b, 0xA5);
			WriteRawRC(0x37, 0xAE);
			WriteRawRC(0x3b, 0x72);
		}
		WriteRawRC(0x37, backup);
	}

	return MI_OK;
}

/////////////////////////////////////////////////////////////////////
// �?    能：置RC522寄存器位
// 参数说明：reg[IN]:寄存器地址
//           mask[IN]:置位�?
/////////////////////////////////////////////////////////////////////
void SetBitMask(unsigned char reg, unsigned char mask)
{
	char tmp = 0x0;
	tmp = ReadRawRC(reg);
	WriteRawRC(reg, tmp | mask); // set bit mask
}

/////////////////////////////////////////////////////////////////////
// �?    能：清RC522寄存器位
// 参数说明：reg[IN]:寄存器地址
//           mask[IN]:清位�?
/////////////////////////////////////////////////////////////////////
void ClearBitMask(unsigned char reg, unsigned char mask)
{
	char tmp = 0x0;
	tmp = ReadRawRC(reg);
	WriteRawRC(reg, tmp & ~mask); // clear bit mask
}

/////////////////////////////////////////////////////////////////////
// �?    能：通过RC522和ISO14443卡通讯
// 参数说明：Command[IN]:RC522命令�?
//           pInData[IN]:通过RC522发送到卡片的数�?
//           InLenByte[IN]:发送数据的字节长度
//           pOutData[OUT]:接收到的卡片返回数据
//           *pOutLenBit[OUT]:返回数据的位长度
/////////////////////////////////////////////////////////////////////
char PcdComMF522(unsigned char Command,
				 unsigned char *pInData,
				 unsigned char InLenByte,
				 unsigned char *pOutData,
				 unsigned int *pOutLenBit)
{
	char status = MI_ERR;
	unsigned char irqEn = 0x00;
	unsigned char waitFor = 0x00;
	unsigned char lastBits;
	unsigned char n;
	unsigned int i;
	switch (Command)
	{
	case PCD_AUTHENT:
		irqEn = 0x12;
		waitFor = 0x10;
		break;
	case PCD_TRANSCEIVE:
		irqEn = 0x77;
		waitFor = 0x30;
		break;
	default:
		break;
	}

	WriteRawRC(ComIEnReg, irqEn | 0x80);
	ClearBitMask(ComIrqReg, 0x80);
	WriteRawRC(CommandReg, PCD_IDLE);
	SetBitMask(FIFOLevelReg, 0x80);

	for (i = 0; i < InLenByte; i++)
	{
		WriteRawRC(FIFODataReg, pInData[i]);
	}
	WriteRawRC(CommandReg, Command);

	if (Command == PCD_TRANSCEIVE)
	{
		SetBitMask(BitFramingReg, 0x80);
	}

	i = 500; // 根据时钟频率调整，操作M1卡最大等待时�?25ms
	do
	{
		n = ReadRawRC(ComIrqReg);
		i--;
	} while ((i != 0) && !(n & 0x01) && !(n & waitFor));
	ClearBitMask(BitFramingReg, 0x80);

	if (i != 0)
	{
		if (!(ReadRawRC(ErrorReg) & 0x1B))
		{
			status = MI_OK;
			if (n & irqEn & 0x01)
			{
				status = MI_NOTAGERR;
			}
			if (Command == PCD_TRANSCEIVE)
			{
				n = ReadRawRC(FIFOLevelReg);
				lastBits = ReadRawRC(ControlReg) & 0x07;
				if (lastBits)
				{
					*pOutLenBit = (n - 1) * 8 + lastBits;
				}
				else
				{
					*pOutLenBit = n * 8;
				}
				if (n == 0)
				{
					n = 1;
				}
				if (n > MAXRLEN)
				{
					n = MAXRLEN;
				}
				for (i = 0; i < n; i++)
				{
					pOutData[i] = ReadRawRC(FIFODataReg);
				}
			}
		}
		else
		{
			status = MI_ERR;
		}
	}

	SetBitMask(ControlReg, 0x80); // stop timer now
	WriteRawRC(CommandReg, PCD_IDLE);
	return status;
}

/////////////////////////////////////////////////////////////////////
// 开启天�?
// 每次启动或关闭天线发射之间应至少�?1ms的间�?
/////////////////////////////////////////////////////////////////////
void PcdAntennaOn()
{
	unsigned char i;
	i = ReadRawRC(TxControlReg);
	if (!(i & 0x03))
	{
		SetBitMask(TxControlReg, 0x03);
	}
}

/////////////////////////////////////////////////////////////////////
// 关闭天线
/////////////////////////////////////////////////////////////////////
void PcdAntennaOff()
{
	ClearBitMask(TxControlReg, 0x03);
}

// 写
unsigned char WriteRawRC(unsigned char addr, unsigned char value)
{
	uint8_t data[2];
	data[0] = addr;
	data[1] = value;
	iic_write(nfc_dev, data, 2);
	return 0x01;
}

// 读
unsigned char ReadRawRC(unsigned char addr)
{
	unsigned char tmp;

	iic_write(nfc_dev, &addr, 1);
	iic_read(nfc_dev, &tmp, 1);
	return tmp;
}
extern uint8_t GetUserNum(char *new);
extern uint32_t GETID(char *new);
extern _rf_total_Data_t rf_ToTalData;
#include "../serial0/include/serial0.h"
#include "../nvs_para/include/nvs_para.h"
extern QueueHandle_t send_data_queue_AT_t;
void rc523_task(void *pvParameters)
{
	static uint32_t tick_start;
	uint8_t cardtype[2];
	while (1)
	{

		if ((PcdRequest(PICC_REQIDL, cardtype)) != 0)
		{
			if ((PcdRequest(PICC_REQIDL, cardtype)) != 0)
			{
				card_info.sta = 0;
			}
			else
			{
				card_info.sta = 1;
			}
		}
		else
		{
			card_info.sta = 1;
		}

		if (card_info.sta)
		{
			if (card_info.last_sta == 0)
			{
				uint8_t i;
				char OUTSTR[200] = {};
				AT_queue_data_t at_result;
				int is_match = 1; // 匹配标志：1=匹配，0=不匹配

				card_info.last_sta = card_info.sta;
				PcdAnticoll(card_info.snr);

				for (i = 0; i < 100; i++)
				{
					is_match = 1;
					if (rf_ToTalData.IDNumData[i].EX == 0x01)
					{
						for (int j = 0; j < 4; j++)
						{
							if (rf_ToTalData.IDNumData[i].rfidID[j] != card_info.snr[j])
							{
								is_match = 0;
								 break;
							}
						}
						if (is_match)
						{
							sprintf(OUTSTR, "Userid: %d\r\nrfid: %.2x%.2x%.2x%.2x\r\n", (int)rf_ToTalData.IDNumData[i].UserID,
									rf_ToTalData.IDNumData[i].rfidID[0],
									rf_ToTalData.IDNumData[i].rfidID[1],
									rf_ToTalData.IDNumData[i].rfidID[2],
									rf_ToTalData.IDNumData[i].rfidID[3]);
							at_result.data = (uint8_t *)OUTSTR;
							at_result.len = strlen(OUTSTR);
							xQueueSendToBack(send_data_queue_AT_t, &at_result, 0);
							break;
						}
					}
				}
				if (i >= 100)
				{
					sprintf(OUTSTR, "There is no such RFID.\r\n");
					// sprintf(OUTSTR, "rfid: %.2x%.2x%.2x%.2x\r\n",
					// 		card_info.snr[0],
					// 		card_info.snr[1],
					// 		card_info.snr[2],
					// 		card_info.snr[3]);
					at_result.data = (uint8_t *)OUTSTR;
					at_result.len = strlen(OUTSTR);
					xQueueSendToBack(send_data_queue_AT_t, &at_result, 0);
				}
			}
		}
		else
		{
			if (card_info.last_sta == 1)
			{
				printf("card out.\r\n");
			}
			card_info.last_sta = 0;
		}
		vTaskDelay(pdMS_TO_TICKS(1000));
	}

	vTaskDelete(NULL);
}
extern char NEWSTR[32];
#include "../finger/include/finger.h"
extern _CS_total_Data_t cs_ToTalData;
extern int rfid;
void Set_rc523_task(void *pvParameters)
{
	static uint32_t tick_start;
	uint8_t cardtype[2];
	while (1)
	{

		if ((PcdRequest(PICC_REQIDL, cardtype)) != 0)
		{
			if ((PcdRequest(PICC_REQIDL, cardtype)) != 0)
			{
				card_info.sta = 0;
			}
			else
			{
				card_info.sta = 1;
			}
		}
		else
		{
			card_info.sta = 1;
		}

		if (card_info.sta)
		{
			if (card_info.last_sta == 0)
			{
				uint8_t i;
				char OUTSTR[200] = {};
				AT_queue_data_t at_result;

				card_info.last_sta = card_info.sta;
				PcdAnticoll(card_info.snr);
				// 新增
				uint32_t UserId = GETID(NEWSTR);
				uint8_t UserNum = GetUserNum(NEWSTR);
				for (i = 0; i < 100; i++)
				{
					if (rfid == 1 || rfid == 3)
					{
						if (rf_ToTalData.IDNumData[i].EX == 0x00)
						{
							for (int j = 0; j < 4; j++)
							{
								rf_ToTalData.IDNumData[i].rfidID[j] = card_info.snr[j];
							}
							rf_ToTalData.IDNumData[i].EX = 0x01;
							rf_ToTalData.IDNumData[i].UserID = UserId;
							rf_ToTalData.IDNumData[i].UserNum = UserNum;
							// 写入命名空间
							nvs_save_ID_data("rfToTal_Data", &rf_ToTalData, sizeof(_rf_total_Data_t));
							break;
						}
					}
					else if (rfid == 2)
					{
						if (rf_ToTalData.IDNumData[i].EX == 0x01 && rf_ToTalData.IDNumData[i].UserID == UserId)
						{
							for (int j = 0; j < 4; j++)
							{
								rf_ToTalData.IDNumData[i].rfidID[j] = card_info.snr[j];
							}
							// 写入命名空间
							nvs_save_ID_data("rfToTal_Data", &rf_ToTalData, sizeof(_rf_total_Data_t));
							break;
						}
					}
				}

				if (i >= 100)
				{
					sprintf(OUTSTR, "The RFID library is full.\r\n");
					at_result.data = (uint8_t *)OUTSTR;
					at_result.len = strlen(OUTSTR);
					xQueueSendToBack(send_data_queue_AT_t, &at_result, 0);
				}

				// 存入指定的统一空间
				if (i < 100 && UserNum > 1)
				{
					for (int j = 0; j < 100; j++)
					{
						if (cs_ToTalData.IDNumData[j].rfidEX == 0x01 && cs_ToTalData.IDNumData[j].UserID == UserId)
						{
							if (cs_ToTalData.IDNumData[j].UserrfidNum < UserNum)
							{
								cs_ToTalData.IDNumData[j].UserrfidNum++;
								cs_ToTalData.IDNumData[j].UserrfidPass = 0;
							}
							break;
						}
					}
				}
				else
				{
					int numj = 0;
					// 第一次录入
					for (numj = 0; numj < 100; numj++)
					{
						// 是否已经有指纹存入过了(或是修改的)
						if (cs_ToTalData.IDNumData[numj].UserID == UserId)
						{
							cs_ToTalData.IDNumData[numj].rfidEX = 0x01;
							if (cs_ToTalData.IDNumData[numj].UserrfidNum < UserNum)
							{
								cs_ToTalData.IDNumData[numj].UserrfidNum++;
								cs_ToTalData.IDNumData[numj].UserrfidPass = 1;
							}
							break;
						}
					}

					if (numj >= 100)
					{
						numj = 0;
						// 完全没有存入过
						for (numj = 0; numj < 100; numj++)
						{
							if (cs_ToTalData.IDNumData[numj].rfidEX == 0x00)
							{
								cs_ToTalData.IDNumData[numj].rfidEX = 0x01;
								if (cs_ToTalData.IDNumData[numj].UserrfidNum < UserNum)
								{
									cs_ToTalData.IDNumData[numj].UserrfidNum++;
									cs_ToTalData.IDNumData[numj].UserrfidPass = 0;
								}
								cs_ToTalData.IDNumData[numj].UserID = UserId;
								cs_ToTalData.IDNumData[numj].Way_data = 1;
								break;
							}
						}
					}
				}
				// 写入命名空间
				nvs_save_ID_data("csToTal_Data", &cs_ToTalData, sizeof(_CS_total_Data_t));

				sprintf(OUTSTR, "AT+RFENTER,%s\r\nOK\r\n", NEWSTR);
				at_result.data = (uint8_t *)OUTSTR;
				at_result.len = strlen(OUTSTR);
				xQueueSendToBack(send_data_queue_AT_t, &at_result, 0);
				// i = PcdSelect(card_info.snr);
				// printf("select card %s.\r\n", (i == 0) ? "suc" : "failed");
			}
		}
		else
		{
			if (card_info.last_sta == 1)
			{
				// 挂起自己，打开检测
				printf("card out.\r\n");
				card_info.last_sta = 0;
				vTaskResume(xGET_rfid_TaskHandle);
				vTaskSuspend(xSET_rfid_TaskHandle);
			}
			card_info.last_sta = 0;
		}
		vTaskDelay(pdMS_TO_TICKS(1000));
	}

	vTaskDelete(NULL);
}

// 版本号
void ReadRC522Version(uint8_t *version)
{
	*version = ReadRawRC(0x37); // 读取VersionReg寄存器
}

void rc523_init(void)
{
	gpio_config_t io_conf = {
		.pin_bit_mask = (1ULL << RST_PIN_NUM),
		.mode = GPIO_MODE_OUTPUT,
		.pull_up_en = GPIO_PULLUP_DISABLE,
		.pull_down_en = GPIO_PULLDOWN_DISABLE,
		.intr_type = GPIO_INTR_DISABLE};
	gpio_config(&io_conf);

	gpio_set_level(RST_PIN_NUM, 1); // Set RST pin high

	nfc_dev = register_iic_device(RC523_ADDR, I2C_SPEED);
	vTaskDelay(pdMS_TO_TICKS(1000));
	// 复位
	PcdReset();
	// 关闭天线
	PcdAntennaOff();
	// 开启天线
	PcdAntennaOn();
	xTaskCreate(rc523_task, "rc523_task", 2024, NULL, 5, &xGET_rfid_TaskHandle);
	xTaskCreate(Set_rc523_task, "Set_rc523_task", 2024, NULL, 5, &xSET_rfid_TaskHandle);
	vTaskSuspend(xSET_rfid_TaskHandle);
}
